package com.take.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.take.common.BaseContext;
import com.take.common.CustomException;
import com.take.dto.DishDto;
import com.take.entity.Dish;
import com.take.entity.DishFlavor;
import com.take.entity.Setmeal;
import com.take.entity.SetmealDish;
import com.take.mapper.DishMapper;
import com.take.service.DishFlavorService;
import com.take.service.DishService;
import com.take.service.SetmealDishService;
import com.take.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private SetmealService setmealService;

    /**
     * 新增菜品，同时保存对应的口味数据
     *
     * @param dishDto
     */
    @Transactional
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到菜品表dish
        this.save(dishDto);

        Long dishId = dishDto.getId();//菜品id

        //菜品口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());

        //保存菜品口味数据到菜品口味表dish_flavor
        dishFlavorService.saveBatch(flavors);

    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     *
     * @param id
     * @return
     */
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息，从dish表查询
        Dish dish = this.getById(id);

        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);

        //查询当前菜品对应的口味信息，从dish_flavor表查询
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dish.getId());
        List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(flavors);

        return dishDto;
    }

    @Override
    @Transactional
    public void updateWithFlavor(DishDto dishDto) {

        //判断当前修改菜品的人是否是admin，如果是admin，则能修改
        Long dishId = dishDto.getId();
        Dish thisDish = this.getById(dishId);
        Long currentId = BaseContext.getCurrentId();
        if(currentId!=1){
            //如果用户不是管理员
            Long createUserId = thisDish.getCreateUser();
            if(!createUserId.equals(currentId)){
                throw new CustomException("失败！当前菜品只能被创建者或者管理员修改");
            }
        }

        //更新dish表基本信息
        this.updateById(dishDto);

        //清理当前菜品对应口味数据---dish_flavor表的delete操作
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());

        dishFlavorService.remove(queryWrapper);

        //添加当前提交过来的口味数据---dish_flavor表的insert操作
        List<DishFlavor> flavors = dishDto.getFlavors();

        flavors = flavors.stream().map((item) -> {
            item.setId(null);  //清空原来的主键
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());

        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 菜品单个删除
     * 1.查询菜品（dish表）的售卖状态,售卖中，则不能删除，
     * 2.如果菜品停售，则查询是否关联套餐（setmeal_dish），如果没关联套餐则直接删除菜品（dish表），
     * 3.如果关联套餐，则不允许删除，则抛出业务异常，
     *
     * @param id
     */
    @Transactional
    public void deleteWithFlavor(Long id) {
        // 1.查询菜品的售卖状态,如果是售卖中，则不能删除，
        //   构造查询条件

        Dish dish = this.getById(id);  //查询出要删除的菜品信息
        Assert.notNull(dish, "要删除的菜品不存在，请检查菜品id是否正确");
        // 得到菜品的售卖状态
        Integer status = dish.getStatus();
        // 如果起售状态,则抛出异常
        if (status == 1) {
            // 起售状态抛出业务异常
            throw new CustomException(dish.getName() + "该菜品正在售卖中，无法删除！请先停售此菜品");
        }
        // 查询该菜品是否关联套餐
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.eq(SetmealDish::getDishId, id);
        // 查到与当前要删的菜品相关联的全部套餐
        List<SetmealDish> setmealDishList = setmealDishService.list(setmealDishLambdaQueryWrapper);

        // 如果菜品没有关联套餐，直接进行逻辑删除
        // setmealDishList没查到数据，所以菜品没有关联套餐，直接进行逻辑删除
        if (setmealDishList.size() == 0) {
            // 调用方法，删除口味
            this.deleteFlavor(id);
            // 调用方法，删除菜品
            this.removeById(dish.getId());
        }else{
            ArrayList<Long> setmealIdList =new ArrayList<>();
            for (SetmealDish setmealDish : setmealDishList) {
                // 获取套餐id的集合
                setmealIdList.add(setmealDish.getSetmealId());
            }
            LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
            setmealLambdaQueryWrapper.in(setmealIdList.size()>0,Setmeal::getId,setmealIdList);
            // setmealList 中存放与此菜品关联的所有套餐
            List<Setmeal> setmealList = setmealService.list(setmealLambdaQueryWrapper);
            ArrayList<String> setmealNameList =new ArrayList<>();
            for (Setmeal setmeal : setmealList) {
                // 获取套餐名称的集合
                setmealNameList.add(setmeal.getName());
            }
            throw new CustomException(setmealNameList + "套餐中包含此菜品，无法删除！");
        }

    }

    //根据菜品id，删除与此菜品管理的口味
    private void deleteFlavor(Long dishId) {
        // 如果菜品没有关联套餐,删除菜品和菜品口味，dish表和dish_flavor表相关信息
        LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DishFlavor::getDishId, dishId);
        List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);
        for (DishFlavor dishFlavor : dishFlavorList) {
            // 删除菜品口味
            dishFlavorService.removeById(dishFlavor.getId());
        }
    }
}
